#include "TimeConverter.h"

//days from 1601/01/01 to 1899/12/30 = 109205
uint64_t TimeConverter::time_diff_history = 109205 * count_100_ns_day;

std::wstring TimeConverter::FileTime_to_wstring(uint64_t ts)
{
    ULARGE_INTEGER ulVal;
    FILETIME fileTime;
    SYSTEMTIME sysTime;
    wchar_t retVal[64] = { 0 };
    int us_count = (ts % 10000) / 10;
    int ns_count = ts % 10;         //unit: 100ns

    ulVal.QuadPart = ts;
    fileTime.dwHighDateTime = ulVal.HighPart;
    fileTime.dwLowDateTime = ulVal.LowPart;

    FileTimeToSystemTime(&fileTime, &sysTime);

    swprintf_s(retVal, L"%d-%02d-%02d %02d:%02d:%02d:%03d:%03d:%d",
        sysTime.wYear, sysTime.wMonth, sysTime.wDay,
        sysTime.wHour, sysTime.wMinute, sysTime.wSecond,
        sysTime.wMilliseconds, us_count, ns_count);

    return wstring(retVal);
}

uint64_t TimeConverter::FileTime_LTC_to_UTC(uint64_t TsLTC)
{
    ULARGE_INTEGER ulVal;
    FILETIME fileTimeUtc;
    FILETIME fileTimeLtc;

    ulVal.QuadPart = TsLTC;

    fileTimeLtc.dwLowDateTime = ulVal.LowPart;
    fileTimeLtc.dwHighDateTime = ulVal.HighPart;

    LocalFileTimeToFileTime(&fileTimeLtc, &fileTimeUtc);

    ulVal.LowPart = fileTimeUtc.dwLowDateTime;
    ulVal.HighPart = fileTimeUtc.dwHighDateTime;

    return ulVal.QuadPart;
}

double TimeConverter::FileTime_to_OLE_Time(uint64_t ts)
{
    double returnVal = 0.0;

    if (ts < time_diff_history)
        return returnVal;    

    auto count_100ns_from1899 = ts - time_diff_history;
    //auto day = count_100ns_from1899 / count_100_ns_day;
    //returnVal = day * 1.0 + count_100ns_from1899 % count_100_ns_day / count_100_ns_day;

    returnVal = count_100ns_from1899*1.0/ count_100_ns_day;
    
    return returnVal;
}

uint64_t TimeConverter::OLE_Time_to_FileTime(double oleTime)
{    
    uint64_t file_time = oleTime * count_100_ns_day + time_diff_history;

    return file_time;
}